<?php
namespace app\system\controller;

use app\base\controller\BaseController;

/**
 * 系统公共类
 */
class SystemController extends BaseController {

    public function __construct() {
        parent::__construct();
        $this->init();
    }

    /**
     * 系统控制器初始化
     */
    protected function init() {

        //判断入口
        if(!defined('SYSTEM_STATUS')){
            $this->error('请从登录入口登录！');
        }
        // 检测用户登录
        define('SYSTEM_ID', $this->isLogin());
        if (!SYSTEM_ID && (APP_NAME <> 'system' || CONTROLLER_NAME <> 'Login')) {
            $this->redirect(url('system/Login/index'));
        }
        if (!(APP_NAME == 'system' && CONTROLLER_NAME == 'Login')) {
            //设置登录用户信息
            $this->loginUserInfo = target('system/SystemUser')->getInfo(SYSTEM_ID);
            //检测权限
            $this->checkPurview();
            //赋值当前菜单
            if (method_exists($this, '_infoModule')) {
                $this->infoModule = $this->_infoModule();
            }
        }
    }

    /**
     * 用户权限检测,日志记录
     */
    protected function checkPurview() {
        $basePurview = $this->loginUserInfo['base_purview'];
        $purviewInfo = service(APP_NAME, 'Purview', 'getSystemPurview');
        if (empty($purviewInfo)) {
            return true;
        }
        $controller = $purviewInfo[CONTROLLER_NAME];
        if (empty($controller['auth'])) {
            return true;
        }
        $action = $controller['auth'][ACTION_NAME];
        if (empty($action)) {
            return true;
        }
        $current = APP_NAME . '_' . CONTROLLER_NAME . '_' . ACTION_NAME;
        if (!empty($basePurview) && !in_array($current, (array)$basePurview) && $this->loginUserInfo['group_id'] <> 1) {
            $this->error('您没有权限访问此功能！');
        }
        //写入日志
        $log = array();
        $log['content'] = $current;
        target('system/SystemLog')->addData('add', $log);
        return true;
    }

    /**
     * 检测用户是否登录
     * @return int 用户IP
     */
    protected function isLogin() {
        $user = session('system_user');
        if (empty($user)) {
            return 0;
        } else {
            return session('system_user_sign') == data_auth_sign($user) ? $user['user_id'] : 0;
        }
    }

    /**
     * 系统模板显示 调用内置的模板引擎显示方法，
     * @access protected
     * @param string $tpl 指定要调用的模板文件
     * @return void
     */
    protected function systemDisplay($tpl = '') {
        //复制当前URL
        $this->assign('self', SELF);
        $this->layout = 'app/system/view/common';
        if (empty($tpl)) {
            $tpl = ACTION_NAME;
        }
        $tpl = 'app/' . strtolower(APP_NAME) . '/view/' . strtolower(CONTROLLER_NAME) . '/' . strtolower($tpl);
        $menuList = target('system/Menu')->getMenu($this->loginUserInfo);
        $this->assign('menuList', $menuList);
        $this->assign('menuJson', json_encode($menuList));
        $html = $this->display($tpl);
    }

    /**
     * 弹出框模板显示
     * @access protected
     * @param string $tpl 指定要调用的模板文件
     * @return void
     */
    protected function dialogDisplay($tpl = '') {
        //复制当前URL
        $this->assign('self', SELF);
        $this->layout = 'app/system/view/commonDialog';
        if (empty($tpl)) {
            $tpl = ACTION_NAME;
        }
        $tpl = 'app/' . strtolower(APP_NAME) . '/view/' . strtolower(CONTROLLER_NAME) . '/' . strtolower($tpl);
        $html = $this->display($tpl);
    }

    /**
     * 分页HTML生成
     * @param  array $map URL参数
     * @return string
     */
    protected function getPageShow($map = array()) {
        $pageArray = $this->pager;
        $html = '
        <ul class="uk-pagination">
          <li><a href="' . $this->createPageUrl($map, $pageArray['firstPage']) . '">首页</a></li>
          <li><a href="' . $this->createPageUrl($map, $pageArray['prevPage']) . '">上一页</a></li> ';
        foreach ($pageArray['allPages'] as $value) {
            if ($value == 0) {
                continue;
            }
            if ($value == $pageArray['page']) {
                $html .= '<li class="uk-active"><span>' . $value . '</span></li> ';
            } else {
                $html .= '<li><a href="' . $this->createPageUrl($map, $value) . '">' . $value . '</a></li> ';
            }
        }
        $html .= '<li><a href="' . $this->createPageUrl($map, $pageArray['nextPage']) . '">下一页</a></li>
          <li><a href="' . $this->createPageUrl($map, $pageArray['lastPage']) . '">末页</a></li>
        </ul>';
        return $html;
    }

    /**
     * 获取url数组
     */
    protected function pageMaps() {
        //生成查询条件
        $model = target($this->_model);
        if (!$model) {
            return array();
        }
        $fields = $model->getFields();
        if (empty($fields)) {
            return array();
        }
        $pageMaps = array();
        foreach ($fields as $val) {
            $value = request($val['Field']);
            if ($value) {
                $pageMaps[$val['Field']] = urldecode($value);
            }
        }
        return $pageMaps;
    }

    /**
     * 通用列表
     */
    public function index() {
        //判断列表开关
        if (method_exists($this, '_index')) {
            if ($this->_index() == false) {
                $this->error404();
            }
        }

        //获取URL参数
        if (method_exists($this, '_indexUrlParam')) {
            $pageMaps = (array)$this->_indexUrlParam();
        } else {
            $pageMaps = $this->pageMaps();
        }

        //生成筛选条件
        if (method_exists($this, '_indexDataWhere')) {
            $where = (array)$this->_indexDataWhere($pageMaps);
        } else {
            $where = $pageMaps;
        }

        //生成分页数量
        if (method_exists($this, '_indexDataPage')) {
            $pageLimit = $this->_indexDataPage($pageMaps);
        } else {
            $pageLimit = 20;
        }

        //生成列表排序
        if (method_exists($this, '_indexDataOrder')) {
            $order = $this->_indexDataOrder($pageMaps);
        }else{
            $order = NULL;
        }

        //生成分页数据
        if (method_exists($this, '_indexData')) {
            $list = $this->_indexData($where, $pageLimit, $order);
        } else {
            $list = target($this->_model)->page($pageLimit)->loadList($where, $pageLimit, $order);
            $this->pager = target($this->_model)->pager;
        }

        //基础赋值
        $this->assign('list', $list);
        $this->assign('page', $this->getPageShow($pageMaps));
        $this->assign('pageMaps', $pageMaps);

        //模板赋值
        if (method_exists($this, '_indexAssign')) {
            foreach ($this->_indexAssign($pageMaps) as $key => $value) {
                $this->assign($key, $value);
            }
        }
        $this->systemDisplay();
    }

    /**
     * 通用添加
     */
    public function add() {
        //判断添加
        if (method_exists($this, '_add')) {
            if ($this->_add() == false) {
                $this->error404();
            }
        }
        if (!IS_POST) {
            //逻辑判断
            if (method_exists($this, '_addLogic')) {
                $this->_addLogic();
            }
            //模板赋值
            if (method_exists($this, '_addAssign')) {
                foreach ($this->_addAssign() as $key => $value) {
                    $this->assign($key, $value);
                }
            }
            $this->systemDisplay('info');
        } else {
            //添加前处理
            if (method_exists($this, '_addBefore')) {
                $data = $this->_addBefore();
            }
            //添加
            $id = target($this->_model)->saveData('add', $data);
            if ($id) {
                //添加后处理
                if (method_exists($this, '_addAfter')) {
                    $this->_addAfter($id);
                }
                $this->success('添加成功！', url('index'));
            } else {
                $msg = target($this->_model)->getError();
                if (empty($msg)) {
                    $this->error('添加失败');
                } else {
                    $this->error($msg);
                }
            }
        }
    }

    /**
     * 通用编辑
     */
    public function edit() {
        //判断编辑
        if (method_exists($this, '_edit')) {
            if ($this->_edit() == false) {
                $this->error404();
            }
        }
        if (!IS_POST) {
            $id = request('get.id', '', 'intval');
            if (empty($id)) {
                $this->error('参数不能为空！');
            }
            //逻辑判断
            if (method_exists($this, '_editLogic')) {
                $this->_editLogic();
            }
            //获取信息
            if (method_exists($this, '_editInfo')) {
                $info = $this->_editInfo();
            } else {
                $model = target($this->_model);
                $info = $model->getInfo($id);
                if (!$info) {
                    $this->error($model->getError());
                }
            }
            //模板赋值
            $this->assign('info', $info);
            if (method_exists($this, '_editAssign')) {
                foreach ($this->_editAssign($info) as $key => $value) {
                    $this->assign($key, $value);
                }
            }
            $this->systemDisplay('info');
        } else {
            //编辑前处理
            if (method_exists($this, '_editBefore')) {
                $data = $this->_editBefore();
            }
            if (target($this->_model)->saveData('edit', $data)) {
                //编辑后处理
                if (method_exists($this, '_editAfter')) {
                    $this->_editAfter($data);
                }
                $this->success('修改成功！', url('index'));
            } else {
                $msg = target($this->_model)->getError();
                if (empty($msg)) {
                    $this->error('修改失败');
                } else {
                    $this->error($msg);
                }
            }
        }
    }

    /**
     * 修改单字段
     */
    public function editAjax() {
        $id = request('post.id');
        $field = request('post.field');
        $val = request('post.val');
        $primary = target($this->_model)->getPrimary();
        if (!$primary) {
            $this->error('未获取到更改主键！');
        }
        if (method_exists($this, '_editAjaxBefore')) {
            $this->_editAjaxBefore($id, $field, $val);
        }
        if(!is_array($field)){
            $field = array( 0 => $field);
            $val = array( 0 => $val);
        }
        target($this->_model)->beginTransaction();
        foreach($field as $key => $vo){
            $where = array();
            $where[$primary] = $id;
            $data = array();
            $data[$vo] = $val[$key];
            if (target($this->_model)->where($where)->data($data)->update() === false) {
                if (method_exists($this, '_editAjaxAfter')) {
                    $this->_editAjaxAfter($id, $field, $val);
                }
                target($this->_model)->rollBack();
                $this->error('更改失败！');
            }
        }
        target($this->_model)->commit();
        $this->success('更改成功！');
    }

    /**
     * 通用删除
     */
    public function del() {
        //判断删除
        if (method_exists($this, '_del')) {
            if ($this->_index() == false) {
                $this->error404();
            }
        }
        $id = request('post.id');
        if (empty($id)) {
            $this->error('参数不能为空！');
        }
        //删除前动作
        if (method_exists($this, '_delBefore')) {
            $data = $this->_delBefore($id);
        }
        //删除动作
        if (target($this->_model)->delData($id)) {
            //删除后处理
            if (method_exists($this, '_delAfter')) {
                $this->_delAfter($id);
            }
            $this->success('删除成功！');
        } else {
            $msg = target($this->_model)->getError();
            if (empty($msg)) {
                $this->error('删除失败！');
            } else {
                $this->error($msg);
            }
        }
    }

}